using Microsoft.Phone.Controls.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
namespace Microsoft.Phone.Controls
{
	public class WrapPanel : Panel
	{
		private bool _ignorePropertyChange;
		public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double), typeof(WrapPanel), new PropertyMetadata(double.NaN, new PropertyChangedCallback(WrapPanel.OnItemHeightOrWidthPropertyChanged)));
		public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double), typeof(WrapPanel), new PropertyMetadata(double.NaN, new PropertyChangedCallback(WrapPanel.OnItemHeightOrWidthPropertyChanged)));
		public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(WrapPanel), new PropertyMetadata(1, new PropertyChangedCallback(WrapPanel.OnOrientationPropertyChanged)));
		[TypeConverter(typeof(LengthConverter))]
		public double ItemHeight
		{
			get
			{
				return (double)base.GetValue(WrapPanel.ItemHeightProperty);
			}
			set
			{
				base.SetValue(WrapPanel.ItemHeightProperty, value);
			}
		}
		[TypeConverter(typeof(LengthConverter))]
		public double ItemWidth
		{
			get
			{
				return (double)base.GetValue(WrapPanel.ItemWidthProperty);
			}
			set
			{
				base.SetValue(WrapPanel.ItemWidthProperty, value);
			}
		}
		public Orientation Orientation
		{
			get
			{
				return (Orientation)base.GetValue(WrapPanel.OrientationProperty);
			}
			set
			{
				base.SetValue(WrapPanel.OrientationProperty, value);
			}
		}
		private static void OnOrientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			WrapPanel wrapPanel = (WrapPanel)d;
			Orientation orientation = (Orientation)e.get_NewValue();
			if (wrapPanel._ignorePropertyChange)
			{
				wrapPanel._ignorePropertyChange = false;
				return;
			}
			if (orientation != 1 && orientation != null)
			{
				wrapPanel._ignorePropertyChange = true;
				wrapPanel.SetValue(WrapPanel.OrientationProperty, (Orientation)e.get_OldValue());
				string text = string.Format(CultureInfo.get_InvariantCulture(), Resources.WrapPanel_OnOrientationPropertyChanged_InvalidValue, new object[]
				{
					orientation
				});
				throw new ArgumentException(text, "value");
			}
			wrapPanel.InvalidateMeasure();
		}
		private static void OnItemHeightOrWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			WrapPanel wrapPanel = (WrapPanel)d;
			double num = (double)e.get_NewValue();
			if (wrapPanel._ignorePropertyChange)
			{
				wrapPanel._ignorePropertyChange = false;
				return;
			}
			if (!num.IsNaN() && (num <= 0.0 || double.IsPositiveInfinity(num)))
			{
				wrapPanel._ignorePropertyChange = true;
				wrapPanel.SetValue(e.get_Property(), (double)e.get_OldValue());
				string text = string.Format(CultureInfo.get_InvariantCulture(), Resources.WrapPanel_OnItemHeightOrWidthPropertyChanged_InvalidValue, new object[]
				{
					num
				});
				throw new ArgumentException(text, "value");
			}
			wrapPanel.InvalidateMeasure();
		}
		protected override Size MeasureOverride(Size constraint)
		{
			Orientation orientation = this.Orientation;
			OrientedSize orientedSize = new OrientedSize(orientation);
			OrientedSize orientedSize2 = new OrientedSize(orientation);
			OrientedSize orientedSize3 = new OrientedSize(orientation, constraint.get_Width(), constraint.get_Height());
			double itemWidth = this.ItemWidth;
			double itemHeight = this.ItemHeight;
			bool flag = !itemWidth.IsNaN();
			bool flag2 = !itemHeight.IsNaN();
			Size size = new Size(flag ? itemWidth : constraint.get_Width(), flag2 ? itemHeight : constraint.get_Height());
			using (IEnumerator<UIElement> enumerator = base.get_Children().GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					UIElement current = enumerator.get_Current();
					current.Measure(size);
					OrientedSize orientedSize4 = new OrientedSize(orientation, flag ? itemWidth : current.get_DesiredSize().get_Width(), flag2 ? itemHeight : current.get_DesiredSize().get_Height());
					if (NumericExtensions.IsGreaterThan(orientedSize.Direct + orientedSize4.Direct, orientedSize3.Direct))
					{
						orientedSize2.Direct = Math.Max(orientedSize.Direct, orientedSize2.Direct);
						orientedSize2.Indirect += orientedSize.Indirect;
						orientedSize = orientedSize4;
						if (NumericExtensions.IsGreaterThan(orientedSize4.Direct, orientedSize3.Direct))
						{
							orientedSize2.Direct = Math.Max(orientedSize4.Direct, orientedSize2.Direct);
							orientedSize2.Indirect += orientedSize4.Indirect;
							orientedSize = new OrientedSize(orientation);
						}
					}
					else
					{
						orientedSize.Direct += orientedSize4.Direct;
						orientedSize.Indirect = Math.Max(orientedSize.Indirect, orientedSize4.Indirect);
					}
				}
			}
			orientedSize2.Direct = Math.Max(orientedSize.Direct, orientedSize2.Direct);
			orientedSize2.Indirect += orientedSize.Indirect;
			return new Size(orientedSize2.Width, orientedSize2.Height);
		}
		protected override Size ArrangeOverride(Size finalSize)
		{
			Orientation orientation = this.Orientation;
			OrientedSize orientedSize = new OrientedSize(orientation);
			OrientedSize orientedSize2 = new OrientedSize(orientation, finalSize.get_Width(), finalSize.get_Height());
			double itemWidth = this.ItemWidth;
			double itemHeight = this.ItemHeight;
			bool flag = !itemWidth.IsNaN();
			bool flag2 = !itemHeight.IsNaN();
			double num = 0.0;
			double? directDelta = (orientation == 1) ? (flag ? new double?(itemWidth) : default(double?)) : (flag2 ? new double?(itemHeight) : default(double?));
			UIElementCollection children = base.get_Children();
			int count = children.get_Count();
			int num2 = 0;
			for (int i = 0; i < count; i++)
			{
				UIElement uIElement = children.get_Item(i);
				OrientedSize orientedSize3 = new OrientedSize(orientation, flag ? itemWidth : uIElement.get_DesiredSize().get_Width(), flag2 ? itemHeight : uIElement.get_DesiredSize().get_Height());
				if (NumericExtensions.IsGreaterThan(orientedSize.Direct + orientedSize3.Direct, orientedSize2.Direct))
				{
					this.ArrangeLine(num2, i, directDelta, num, orientedSize.Indirect);
					num += orientedSize.Indirect;
					orientedSize = orientedSize3;
					if (NumericExtensions.IsGreaterThan(orientedSize3.Direct, orientedSize2.Direct))
					{
						this.ArrangeLine(i, ++i, directDelta, num, orientedSize3.Indirect);
						num += orientedSize.Indirect;
						orientedSize = new OrientedSize(orientation);
					}
					num2 = i;
				}
				else
				{
					orientedSize.Direct += orientedSize3.Direct;
					orientedSize.Indirect = Math.Max(orientedSize.Indirect, orientedSize3.Indirect);
				}
			}
			if (num2 < count)
			{
				this.ArrangeLine(num2, count, directDelta, num, orientedSize.Indirect);
			}
			return finalSize;
		}
		private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double indirectOffset, double indirectGrowth)
		{
			double num = 0.0;
			Orientation orientation = this.Orientation;
			bool flag = orientation == 1;
			UIElementCollection children = base.get_Children();
			for (int i = lineStart; i < lineEnd; i++)
			{
				UIElement uIElement = children.get_Item(i);
				OrientedSize orientedSize = new OrientedSize(orientation, uIElement.get_DesiredSize().get_Width(), uIElement.get_DesiredSize().get_Height());
				double num2 = directDelta.get_HasValue() ? directDelta.get_Value() : orientedSize.Direct;
				Rect rect = flag ? new Rect(num, indirectOffset, num2, indirectGrowth) : new Rect(indirectOffset, num, indirectGrowth, num2);
				uIElement.Arrange(rect);
				num += num2;
			}
		}
	}
}
